package com.app.business.service;

import com.app.business.calculate.CalculateUtils;
import com.app.business.en.Status;
import com.app.business.model.AdjustArea;
import com.app.business.model.Contract;
import com.app.system.jpa.JpaBaseDao;
import com.app.system.jpa.PageBean;
import com.app.system.jpa.Wrapper;
import com.app.system.permission.model.UserInfo;
import com.app.system.utils.CollectionUtils;
import com.app.system.utils.ParamUtils;
import com.app.system.utils.WebUtils;
import com.app.system.utils.dataType.BigDecimalUtils;
import com.app.system.utils.dataType.DateUtils;
import com.app.system.utils.exception.Precondition;
import com.app.system.utils.exception.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 面积调换管理
 * Created by ddz on 2019/2/12.
 */
@SuppressWarnings(value = "ALL")
@Service
public class AdjustAreaService extends JpaBaseDao<AdjustArea, Integer> {

    @Autowired
    private ContractService contractService;

    /**
     * 根据协议Id得到调剂记录
     *
     * @param contractId
     * @return
     */
    public List<AdjustArea> getAdjustAreaListByContractId(Integer contractId) {
        //查询语句
        String hql = " from AdjustArea aa where aa.contract.id = :contractId order by aa.doDate desc";
        Map<String, Object> map = new HashMap<>();
        map.put("contractId", contractId);
        return this.findHql(hql, map);
    }

    /**
     * 需删除的明细
     * @param adjustArea
     * @return
     */
    public List<AdjustArea> getDeleteListByAdjustInfo(AdjustArea adjustArea) {
        //查询语句
        String hql = " from AdjustArea aa where aa.outContractId = :outContractId and aa.inContractId = :inContractId ";
        Map<String, Object> map = new HashMap<>();
        map.put("outContractId", adjustArea.getOutContractId());
        map.put("inContractId", adjustArea.getInContractId());
        return this.findHql(hql, map);
    }

    public PageBean<AdjustArea> adjustAreaPageBeanByContractId(Integer contractId) {
        //查询语句
        StringBuffer query = new StringBuffer(" a from AdjustArea a  ");
        //默认排序(PageBean指定排序字段类型的话，则默认排序不使用)
        StringBuffer orderBy = new StringBuffer(" a.id ");
        Wrapper wrapper = new Wrapper(query, orderBy);
        wrapper.initSearchParams();
        wrapper.getPageBean().setPageSize(5);
        wrapper.andEq("a.contract.id", contractId);
        return this.pageHql(wrapper);
    }

    /**
     * 面积调剂保存
     *
     * @param request
     * @return
     */
    @Transactional
    public synchronized Response setAreaSave(HttpServletRequest request) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        //得到转出方和接受方ID及协议
        int outContractId = ParamUtils.getInt(request, "outContractId", 0);
        int inContractId = ParamUtils.getInt(request, "inContractId", 0);
        //得到转出面积
        BigDecimal area = ParamUtils.getDecimal(request, "area", 0);
        Precondition.checkAjaxArguement(area.compareTo(BigDecimal.ZERO) > 0, "1111", "数据错误！");

        Contract outContract = this.contractService.findOne(outContractId);//转出方
        Contract inContract = this.contractService.findOne(inContractId);//转入方
        Precondition.checkAjaxArguement(area.compareTo(outContract.getLimitHouseAreaTotal()) <= 0, "1111", "转出面积超出转出方总可选房面积！");
        //保存调剂面积记录
        this.saveAdjustArea(outContract, inContract, area);
        BigDecimal newOutAdjustArea = null;
        BigDecimal newInAdjustArea = null;

        //保存转出方调剂面积
        List<AdjustArea> outAdjustAreaList = this.getAdjustAreaListByContractId(outContractId);
        if (CollectionUtils.isNotEmpty(outAdjustAreaList)) {
            Map<String, Object> item = null;
            for (AdjustArea outAdjustArea : outAdjustAreaList) {
                newOutAdjustArea = BigDecimalUtils.getSum(newOutAdjustArea, outAdjustArea.getAdjustArea());
            }
            outContract.setAdjustArea(newOutAdjustArea);
            this.contractService.save(outContract);
        }
        //保存转入方调剂面积
        List<AdjustArea> inAdjustAreaList = this.getAdjustAreaListByContractId(inContractId);
        if (!CollectionUtils.isEmpty(inAdjustAreaList)) {
            Map<String, Object> item = null;
            for (AdjustArea inAdjustArea : inAdjustAreaList) {
                newInAdjustArea = BigDecimalUtils.getSum(newInAdjustArea, inAdjustArea.getAdjustArea());
            }
            inContract.setAdjustArea(newInAdjustArea);
            this.contractService.save(inContract);
        }
        CalculateUtils.main(outContractId);
        CalculateUtils.main(inContractId);
        return new Response("0001", "保存成功");
    }

    /**
     * 保存双方记录
     *
     * @param outContract
     * @param inContract
     * @param area
     */
    @Transactional
    public void saveAdjustArea(Contract outContract, Contract inContract, BigDecimal area) {
        //得到操作人
        String doName = WebUtils.getLoginUserInfo().getName();
        //保存转出方记录
        AdjustArea adjustArea1 = new AdjustArea();
        adjustArea1.setAdjustArea(BigDecimalUtils.getBigAndBigSub(new BigDecimal("0"), area));
        adjustArea1.setContract(outContract);
        adjustArea1.setDoDate(new Date());
        adjustArea1.setDoName(doName);
        adjustArea1.setInContractId(inContract.getId());
        adjustArea1.setOutContractId(outContract.getId());
        adjustArea1.setMemo(outContract.getContractCode() + "转给" + inContract.getContractCode() + "【" + area + "】㎡");
        this.save(adjustArea1);
        //保存接受方记录
        AdjustArea adjustArea2 = new AdjustArea();
        adjustArea2.setAdjustArea(area);
        adjustArea2.setContract(inContract);
        adjustArea2.setDoDate(new Date());
        adjustArea2.setDoName(doName);
        adjustArea2.setInContractId(inContract.getId());
        adjustArea2.setOutContractId(outContract.getId());
        adjustArea2.setMemo(inContract.getContractCode() + "接收" + outContract.getContractCode() + "【" + area + "】㎡");
        this.save(adjustArea2);
    }
}